/*
 * error.c
 *
 *  Created on: 2015-5-15
 *      Author: likui
 */

#include "error.h"

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <syslog.h>

#define MAXLINE	8192
#define STR_ON		1
#define STR_OFF 	0

static void error_doit( int flag, int level, const char *fmt, va_list ap);

int		daemon_proc;

/**
 * @brief 文件作用域函数。构造并输出提示信息
 * @param flag 若为 STR_ON 则显示字符提示，若为 STR_OFF	则不显示字符提示
 * @param level LOG_ERR 出错提示
 *				LOG_INFO 信息提示
 * @param fmt	待格式化字符串
 * @param ap	不定参数
 * @return 无
 */
static void error_doit( int flag, int level, const char *fmt, va_list ap)
{
	char	errno_save, n;
	char	buf[MAXLINE + 1];

	errno_save = errno;
	vsnprintf(buf, MAXLINE, fmt, ap);

	n = strlen (buf);

	// 是否有除错信息
	if (flag) {
		snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
		n = strlen (buf);
	}

	strncat(buf, "\n", MAXLINE - n);

	if (daemon_proc) {
		syslog(level, buf);
	} else {
		fflush(stdout);
		fputs(buf, stderr);
		fflush(stderr);
	}

	return;

}

/**
 * @brief 非致命错误，与系统调用相关。输出出错消息并返回。输出errno信息。
 * @param fmt 待格式化字符串
 * @return 无返回值
 */
void error_ret(const char *fmt, ...)
{
	va_list		ap;

	va_start(ap, fmt);
	error_doit(STR_ON, LOG_INFO, fmt, ap);
	va_end(ap);

	return;
}

/**
 * @brief 致命错误，与系统调用相关。输出出错信息并终止。输出errno信息。
 * @param fmt 待格式化字符串
 * @return 无返回值
 */
void error_sys(const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	error_doit(STR_ON, LOG_ERR, fmt, ap);
	va_end(ap);

	exit(1);
}

/**
 * @brief 致命错误，与系统调用相关。输出出错信息，转存储，并终止。输出errno信息。
 * @param fmt 待格式化字符串
 * @return 无返回值
 */
void error_dump(const char *fmt, ...)
{
	va_list		ap;

	va_start(ap, fmt);
	error_doit(STR_ON, LOG_ERR, fmt, ap);
	va_end(ap);
	abort();

	exit(1);
}

/**
 * @brief 非致命错误，与系统调用无关。输出出错信息并返回。
 * @param fmt 待格式化字符串
 * @return 无返回值
 */
void error_msg(const char *fmt, ...)
{
	va_list		ap;

	va_start(ap, fmt);
	error_doit(STR_OFF, LOG_INFO, fmt, ap);
	va_end(ap);

	return;
}

/**
 * @brief 致命错误，与系统调用无关。输出除错信息并终止。
 * @param fmt 待格式化字符串
 * @return 无返回值
 */
void error_quit(const char *fmt, ...)
{
	va_list		ap;

	va_start(ap, fmt);
	error_doit(STR_OFF, LOG_ERR, fmt, ap);
	va_end(ap);
	exit(1);
}
